#include "main.h"
//// C lib
//#include <stdlib.h>
//#include <string.h>
//#include <stdio.h>
//// system
//#include "delay.h"
// GSM
#include "GSM_config.h"


static char* GSM_check_cmd(char *str);
static void GSM_sendData(char* fmt,...);

// GSM信息
const char* GSM_phoneNum = "19198022169";
const char* GSM_head = "send:";

/**
  * @brief  向GSM串口发送数据
  * @param  fmt: 类似printf的数据格式
  * @retval None
  * @note   None
  */
void GSM_sendData(char* fmt,...)  
{  
	uint16_t i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)GSM_USART_TX_BUF,fmt,ap);
	va_end(ap);
	i = strlen((const char*)GSM_USART_TX_BUF);		
	for(j=0; j<i; j++)						
	{
	  while(USART_GetFlagStatus(GSM_USARTx,USART_FLAG_TC)==RESET); 
		USART_SendData(GSM_USARTx,GSM_USART_TX_BUF[j]); 
	} 
}
/**
  * @brief  检测应答
  * @param  str: 期待的应答结果
  * @retval 0: 没有接收到期待应答
  * @retval !0: 其他值代表期待应答结果的位置
  * @note   None
  */
static char* GSM_check_cmd(char *str)
{
	char *strx=0;
	// 接收到一次数据了
	if(GSM_USART_RX_STA&0X8000)		
	{ 
		// 添加结束符
		GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;
		// 检索字符串
		strx=strstr(GSM_USART_RX_BUF,str);
		#ifdef DEBUG_printf
		printf("rec data: %s\n",GSM_USART_RX_BUF);
		#endif
	} 
	return strx;
}
/**
  * @brief  向GSM发送命令
  * @param  cmd: 发送的命令字符串
  * @param	ack: 期待的应答结果,如果为空,则表示不需要等待应答
  * @param	waittime: 等待时间(单位:10ms)
  * @retval 0: 发送成功(得到了期待的应答结果), 
  * @retval	1: 发送失败
  * @note   None
  */
char GSM_send_cmd(char *cmd,char *ack,uint16_t waittime)
{
	char res=0; 
	GSM_USART_RX_STA=0;
	//发送命令
	GSM_sendData("%s",cmd);	
	if(ack&&waittime)		//需要等待应答
	{
		while(--waittime)	//等待倒计时
		{
			DELAYClass.DelayMs(10);
			if(GSM_USART_RX_STA&0X8000)//接收到期待的应答结果
			{
				if(GSM_check_cmd(ack) != ((void *)0))
				{
					break; // 得到有效数据 
				}
				GSM_USART_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
} 
/**
  * @brief  string转换int
  * @param  *str:字符串地址
  * @retval 返回int型
  * @note   None
  */
int stringToInt(char *str)
{
	char *p = str;
	int nNUM = 0;
	
	while (*p >= '0' && *p <= '9')
	{
		nNUM = nNUM * 10 + (*p - '0');
		p++;
	}
	return nNUM;
}
/**
  * @brief  发送短信
  * @param  None
  * @retval None
  */
void GSM_sendMessage(char *message)
{
	char p[40];

	#ifdef DEBUG_printf
	printf("0. AT+CPIN?\n");
	#endif
	while(GSM_send_cmd("AT+CPIN?\r\n","OK",100));		// 查询卡状态
	#ifdef DEBUG_printf
	printf("1. AT+CMGF=1\n");
	#endif
	while(GSM_send_cmd("AT+CMGF=1\r\n","OK",100));		// 设置TXT模式
	#ifdef DEBUG_printf
	printf("2. AT+CMGS=\n");
	#endif
	sprintf((char*)p,"AT+CMGS=\"%s\"\r\n",GSM_phoneNum); // 设置目标手机号
	while(GSM_send_cmd(p,">",100));  
	DELAYClass.DelayMs(50);
	#ifdef DEBUG_printf
	printf("3. %s\n",message);
	#endif
	sprintf((char*)p,"%s\r\n",message); // 设置发送内容
	GSM_send_cmd(p,">",100);  
	DELAYClass.DelayMs(50);
	#ifdef DEBUG_printf
	printf("4. %x\n", 0x1A);
	#endif
	USART_SendData(USART2, 0x1A); // 确认发送
}
/**
  * @brief  等待接收短信
  * @param  None
  * @retval 0：无短信，!0：接收到的短信的存放地址
  */
uint8_t GSM_waitMessage(void)
{
	// 接收到一次数据了
	if(GSM_USART_RX_STA&0X8000)		
	{ 
		GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0; // 添加结束符
#ifdef DEBUG_printf
		printf("(waitMes)%s\n", GSM_USART_RX_BUF);
#endif		
		char *strx = 0;
		// 检索字符串  含有"SM",则代表接收到短信
		strx=strstr(GSM_USART_RX_BUF,"\"SM\",");
		// 返回不为空则检索到指定字符串
		if(strx != ((void *)0))
		{
#ifdef DEBUG_printf
			printf("message rec success, addr : %d\n", stringToInt(strx+5));
#endif
			uint8_t addrNum = stringToInt(strx+5); // 将地址号保存
			GSM_USART_RX_STA = 0; // 清除接收标记
			return addrNum;
		}
		GSM_USART_RX_STA = 0;
	} 
	return 0;
}
/**
  * @brief  查看短信
  * @param  None
  * @retval 返回帧头后的一个字节数据
  */
char GSM_readMessage(uint8_t addrNum)
{
	char pp[40];
	uint8_t i = 0;
	sprintf((char*)pp,"AT+CMGR=%d\r\n",addrNum); // 查看该地址下的短信
	GSM_USART_RX_STA = 0;
	// 等待2s
	for(i = 0; i <= 200; i++) 
	{
		if(i % 50 == 0) // 每0.5s重发一次
		{
#ifdef DEBUG_printf
			printf("i = %d\n", i);
#endif
			GSM_sendData("%s", pp);
		}
		DELAYClass.DelayMs(10);
		if(GSM_USART_RX_STA&0X8000)		
		{ 
			// 添加结束符
			GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;
#ifdef DEBUG_printf
			printf("(readMes)%s\n", GSM_USART_RX_BUF);
#endif
			char *strx = 0;
			// 检索字符串  含有"send:",则代表查看短信成功
			strx=strstr(GSM_USART_RX_BUF,GSM_head);
			// 返回不为空则检索到指定字符串
			if(strx != ((void *)0))
			{
#ifdef DEBUG_printf
				printf("message read success, cmd : %c\n", strx[5]);
#endif
				char cmd = 0;
				cmd = strx[5]; // 此处可根据需求修改 当前是返回的send:后的一个字节
				GSM_USART_RX_STA = 0; // 清除接收标记
				DELAYClass.DelayMs(10);
				sprintf((char*)pp,"AT+CMGD=%d\r\n",addrNum); // 删除该地址下的短信
				GSM_sendData("%s", pp);
				return cmd;
			}
			GSM_USART_RX_STA = 0;
		}
	}
	GSM_USART_RX_STA = 0;
	return 0;
}
/**
  * @brief  GSM初始化
  * @param  None
  * @retval None
  * @note   None
	*/
void GSM_Init(void)
{
	GSM_USART_Init(9600);
	GSM_TIM3_Init();
}
